package com.seezoon.domain.service.user;

import com.seezoon.domain.dao.mapper.UserInfoMapper;
import com.seezoon.domain.dao.po.UserInfoPO;
import com.seezoon.infrastructure.error.ErrorCode;
import com.seezoon.infrastructure.exception.Assertion;
import com.seezoon.infrastructure.exception.ExceptionFactory;
import com.seezoon.infrastructure.security.PasswordEncoder;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

/**
 * 用户服务
 */
@RequiredArgsConstructor
@Slf4j
@Service
@Validated
public class UserInfoService {

    private final UserInfoMapper userInfoMapper;

    @Transactional
    public String resetSecretKey(@NotNull Long uid) {
        UserInfoPO userInfoPO = userInfoMapper.selectByPrimaryKey(uid);
        if (userInfoPO == null) {
            throw ExceptionFactory.bizException(ErrorCode.USER_NOT_EXISTS);
        }
        String secretKey = this.genSecretKey();
        UserInfoPO update = new UserInfoPO();
        update.setUid(uid);
        update.setSecretKey(secretKey);
        update.setUpdateTime(Instant.now());
        int affectedRow = this.userInfoMapper.updateByPrimaryKeySelective(update);
        Assertion.affectedOne(affectedRow);
        return secretKey;
    }

    /**
     * 重置用户密码
     *
     * @param username 用户名（手机号或邮箱）
     * @param newPassword 新密码
     * @return 用户ID
     */
    @Transactional
    public Long resetPassword(@NotEmpty String username, @NotEmpty String newPassword) {
        UserInfoPO userInfoPO = userInfoMapper.selectByUsername(username);
        if (userInfoPO == null) {
            throw ExceptionFactory.bizException(ErrorCode.USER_NOT_EXISTS);
        }

        UserInfoPO updateUser = new UserInfoPO();
        updateUser.setUid(userInfoPO.getUid());
        updateUser.setPassword(PasswordEncoder.encode(newPassword));
        updateUser.setUpdateTime(Instant.now());

        int affectedRows = userInfoMapper.updateByPrimaryKeySelective(updateUser);
        Assertion.affectedOne(affectedRows);

        log.info("user reset password success uid:{}", userInfoPO.getUid());
        return userInfoPO.getUid();
    }

    public String genSecretKey() {
        return RandomStringUtils.randomAlphanumeric(32);
    }

}
